#include"SPU.h"

inline std::vector<uint64_t>* scalar_reg2vec_reg(uint64_t scalar_value) {
    std::vector<uint64_t>* vec_value = new std::vector<uint64_t>(16, scalar_value);
    return vec_value;
}

void SPU::Execute_SMAC1(instruction* smac_instr) {
    if (smac_instr->get_opcode() == SVBCAST2) {
        // 特例处理SVBCAST2指令
        std::cout << "Executing SVBCAST2 instruction in SPU." << std::endl;
        int src_reg_id = static_cast<register_operand*>(smac_instr->get_operands(0))->get_reg_id();
        int dst_reg_id = static_cast<register_operand*>(smac_instr->get_operands(1))->get_reg_id();
        
        uint64_t src_value_1 = this->SMAC1->read_Reg(src_reg_id);
        uint64_t src_value_2 = this->SMAC1->read_Reg(src_reg_id + 1);
        // 简单广播：将两个src_value分别写入对应的两个目标寄存器
        this->WCM->post_write_req(dst_reg_id, scalar_reg2vec_reg(src_value_1), 4);
        this->WCM->post_write_req(dst_reg_id + 1, scalar_reg2vec_reg(src_value_2), 4);

        std::cout << "SVBCAST2 wrote value " << src_value_1 << " to registers " << dst_reg_id << " and " << dst_reg_id + 1 << std::endl;
        return; // 直接返回，不进行后续处理
    }
    //执行SMAC1指令
    write_req_info_reg buffer;
    uint64_t res = this->SMAC1->Execute(smac_instr);
    buffer = this->SMAC1->upload_write_msg();

    assert(res == buffer.value && "SMAC1 execution result mismatch!");
    //提交写入请求
    this->WCM->post_write_req(buffer.reg_id, res, buffer.delay);
}

void SPU::Execute_SMAC2(instruction* smac_instr) {
    //执行SMAC2指令
    if (smac_instr->get_opcode() == SVBCAST2) {
        // 特例处理SVBCAST2指令
        std::cout << "Executing SVBCAST2 instruction in SPU." << std::endl;
        int src_reg_id = static_cast<register_operand*>(smac_instr->get_operands(0))->get_reg_id();
        int dst_reg_id = static_cast<register_operand*>(smac_instr->get_operands(1))->get_reg_id();
        
        uint64_t src_value_1 = this->SMAC2->read_Reg(src_reg_id);
        uint64_t src_value_2 = this->SMAC2->read_Reg(src_reg_id + 1);
        // 简单广播：将两个src_value分别写入对应的两个目标寄存器
        this->WCM->post_write_req(dst_reg_id, scalar_reg2vec_reg(src_value_1), 4);
        this->WCM->post_write_req(dst_reg_id + 1, scalar_reg2vec_reg(src_value_2), 4);

        std::cout << "SVBCAST2 wrote value " << src_value_1 << " to registers " << dst_reg_id << " and " << dst_reg_id + 1 << std::endl;
        return; // 直接返回，不进行后续处理
    }
    write_req_info_reg buffer;
    uint64_t res = this->SMAC2->Execute(smac_instr);
    buffer = this->SMAC2->upload_write_msg();

    assert(res == buffer.value && "SMAC2 execution result mismatch!");
    //提交写入请求
    this->WCM->post_write_req(buffer.reg_id, res, buffer.delay);
}

void SPU::Execute_SIEU(instruction* sieu_instr) {
    //执行SIEU指令
    write_req_info_reg buffer;
    uint64_t res = this->SIEU_unit->Execute(sieu_instr);
    buffer = this->SIEU_unit->upload_write_msg();
    std::cout << "SIEU execution result: " << res << "/"<< buffer.value << ", buffer reg id: " << buffer.reg_id << std::endl;   

    assert(res == buffer.value && "SIEU execution result mismatch!");
    //提交写入请求
    this->WCM->post_write_req(buffer.reg_id, res, buffer.delay);
}

void SPU::Execute_SLDST(instruction* sldst_instr) {
    //执行SLDST指令
    std::cout << "Executing SLDST instruction..." << std::endl;
    this->SLDST_unit->Execute(sldst_instr);
}

void SPU::Execute_SBR(instruction* sbr_instr) {
    std::cout << "Executing SBR instruction..." << std::endl;
    //执行SBR指令
    // this->SBR_unit->Execute(sbr_instr);
}